import numpy as np


class Turn:
    def __init__(self, transcript, system_transcript, turn_label):
        self.transcript = transcript
        self.turn_label = turn_label
        self.system_transcript = system_transcript

    def to_dict(self):
        return {
                'transcript': self.transcript,
                'turn_label': self.turn_label,
                'system_transcript': self.system_transcript,
               }

    @classmethod
    def from_dict(cls, d):
        return cls(**d)

    @classmethod
    def get_turn_label(cls, acts):
        result = []
        reserve_value = {'是', '否', 'none', ''}
        reserve_slot = {'none', ''}
        for act in acts:
            if act[2] not in reserve_slot and act[3] not in reserve_value:
                result.append([act[2], act[3]])
        return result


    @classmethod
    def from_turns(cls, turns):
        sys_utterance = ''
        result = []
        for turn in turns:
            if turn['role'] == 'sys':
                sys_utterance = turn['utterance']
                continue
            else:
                next_turn = Turn(turn['utterance'], sys_utterance, Turn.get_turn_label(turn['dialog_act']))
                result.append(next_turn)
        return result

class Dialogue:
    def __init__(self, turns):
        self.turns = turns

    def __len__(self):
        return len(self.turns)

    def to_dict(self):
        return {'turns': [t.to_dict() for t in self.turns]}

    @classmethod
    def from_dict(cls, d):
        return cls(Turn.from_turns(d['turns']))


class Dataset:
    def __init__(self, dialogues):
        self.dialogues = dialogues

    def __len__(self):
        return len(self.dialogues)

    def iter_turns(self):
        for d in self.dialogues:
            for t in d.turns:
                yield t

    def to_dict(self):
        return {'dialogues': [d.to_dict() for d in self.dialogues]}

    @classmethod
    def from_dict(cls, d):
        return cls([Dialogue.from_dict(dd) for dd in d])


class Ontology:
    def __init__(self, slots=None, values=None):
        self.slots = slots or {}
        self.values = values or {}

    def to_dict(self):
        return {'slots': self.slots, 'values': self.values}

    @classmethod
    def from_dicts(cls, dicts):
        slots = set()
        values = {}
        reserve_value = {'是','否','none',''}
        reserve_slot = {'none',''}
        for obj in dicts:
            for dialog in obj:
                for turn in dialog['turns']:
                    if turn['role'] == 'usr':
                        for dialog_act in turn['dialog_act']:
                            if dialog_act[2] not in reserve_slot and dialog_act[3] not in reserve_value:
                                slots.add(dialog_act[2])
                                values.setdefault(dialog_act[2], [])
                                values[dialog_act[2]].append(dialog_act[3])
        slots = list(slots)
        return cls(slots, values)
